import React, { useCallback, useEffect, useRef, useState } from "react";
import { Span } from "./span";
import { useSize } from "../utils/use-size";

export type SVGFontProps = {
  children: React.ReactNode;
  styles?: React.CSSProperties;
};

const SVGFont = ({ children, styles }: SVGFontProps) => {
  const SVGRef = useRef(null) as any;
  const [bound, setBound] = useState({ width: 0, height: 0 });
  const size = useSize(SVGRef);

  const getBox = useCallback(() => {
    return (SVGRef.current as SVGGraphicsElement)?.getBBox?.();
  }, []);

  const resetSVG = useCallback((xy = true) => {
    const svg = getBox();
    setBound({
      width: Math.ceil(svg?.width),
      height: Math.ceil(svg?.height),
    });
  }, []);

  useEffect(() => {
    resetSVG(false);
  }, [size]);

  useEffect(() => {
    document.fonts.ready.then(() => {
      resetSVG(true);
    });
    return () => {
      SVGRef.current = null;
    };
  }, []);

  useEffect(() => {
    resetSVG(false);
  }, [children]);

  return (
    <>
      <svg
        width={bound?.width || 0}
        height={bound?.height || 0}
        ref={SVGRef}
        style={{ ...styles }}
      >
        <text
          x="0"
          y={Math.ceil(Math.abs((bound?.height || 0) / 1.15)) || 0}
          style={{
            lineHeight: 1.15,
          }}
        >
          {children}
        </text>
      </svg>
    </>
  );
};

SVGFont.Span = Span;

export { SVGFont };
